import argparse
import datetime
import json
import logging
import os


import autopep8
from jinja2 import Environment

"""
pip3 install -r requirements.txt -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
"""

# 将模板压缩成单一字符的原因是方便打包
temp_str = '#!/usr/bin/env python\n# -*-coding:utf-8-*-\n# creat by har2py\n# Date {{ creatime.strftime("%Y-%m-%d %H:%M:%S") }}\n\nimport requests\nrequests.packages.urllib3.disable_warnings()\n\nsess = requests.session()\nheaders = {{headers}}\nurl = "{{url}}"\n\nsess.headers = headers\n\nparams = {{params | default(None)}}\njsondata = {{jsondata | default(None)}}\n{% if istextbody %}\n'
t2 = "postdata = '''{{postdata}}'''\n{% else %}\npostdata = {{postdata | default(None)}}\n{% endif %}\n\n\nresp = sess.{{method | lower}}(url, verify=False, json=jsondata, data=postdata, params=params)\nprint(resp.text)\n"
temp_str += t2


class Har2py:

    def __init__(self, request_dict):
        self.url = request_dict['url'].split('?')[0]
        self.method = request_dict['method']
        self.headers = self.dictlist_handle(request_dict['headers'])
        self.query = self.dictlist_handle(request_dict['queryString'])
        self.request_dict = request_dict
        self.istextbody = False
        self.post_data = None
        self.json_data = None
        self.post_data_handle()

    @classmethod
    def dictlist_handle(cls, header_list):
        dict_data = {}
        for head in header_list:
            dict_data[head['name']] = head['value']
        if dict_data:
            return dict_data

    def post_data_handle(self):
        request_dict = self.request_dict
        body_data = request_dict['postData'].get('text', None)
        try:
            json_data = json.loads(body_data)
        except Exception as e:
            self.post_data = body_data
            if body_data:
                self.istextbody = True
            else:
                self.post_data = None
        else:
            self.json_data = json_data
        # web表单处理
        post_form_data = request_dict['postData'].get('params', None)
        if post_form_data:
            post_data = self.dictlist_handle(post_form_data)
            self.post_data = post_data
            if len(post_data) == 1:
                if list(post_data.keys())[0] is None:
                    self.post_data = post_data[None]
                    self.istextbody = True

    def render(self):
        env = Environment()
        temp = env.from_string(temp_str)
        res = temp.render(headers=self.headers, url=self.url, method=self.method, postdata=self.post_data,
                          jsondata=self.json_data, params=self.query, istextbody=self.istextbody,
                          creatime=datetime.datetime.now())
        res = autopep8.fix_code(res, options={'max_line_length': 100})
        return res


def genrate_file(harfile, output_dir):
    fp = open(harfile, 'r', encoding='utf-8')
    content = fp.read()
    if content.startswith(u'\ufeff'):
        content = content.encode('utf8')[3:].decode('utf8')

    log_dict = json.loads(content)
    request_list = log_dict['log']['entries']
    for req_dict in request_list:
        req_obj = Har2py(req_dict['request'])
        filename = req_obj.url.split('/')[-1]
        filename = filename.replace('/', '').replace(':', '')
        count = 0
        while os.path.isfile(os.path.join(output_dir, filename + '.py')):
            count += 1
            filename += str(count)
        filename = os.path.join(output_dir, filename + '.py')

        with open(filename, 'w', encoding='utf-8') as fs:
            fs.write(req_obj.render())
        logging.info("gernerate in {}".format(filename))


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("-v", "--verbosity", help="show version", action="store_true")
    parser.add_argument("har", help="input file path")
    parser.add_argument("-o", "--outdir", help="output dir", default=os.getcwd())
    parser.add_argument(
        '--log-level', default='INFO',
        help="Specify logging level, default is INFO.")
    args = parser.parse_args()

    log_level = getattr(logging, args.log_level.upper())
    logging.basicConfig(level=log_level)
    genrate_file(args.har, args.outdir)


if __name__ == '__main__':
    main()
